package com.tanhua.appserver.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.appserver.exception.BusinessException;
import com.tanhua.appserver.hanlder.UserHolder;
import com.tanhua.autoconfig.template.OosTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbointerface.api.CommentApi;
import com.tanhua.dubbointerface.api.MovementApi;
import com.tanhua.dubbointerface.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.utills.CommentType;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MovementsService {



    @DubboReference
    private MovementApi movementApi;
    @DubboReference
    private CommentApi commentApi;

    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private OosTemplate oosTemplate;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    /**
     * 发布动态
     * @param movement
     * @param imageContent
     * @throws IOException
     */
    public void publish(Movement movement, MultipartFile[] imageContent) throws IOException {
        Long userId = UserHolder.getUserId();
        if (movement==null){
            throw new BusinessException(ErrorResult.contentError());
        }
        List<String> medias= new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String url = oosTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(url);

        }
        movement.setUserId(userId);
        movement.setMedias(medias);
        movementApi.publish(movement);
    }

    /**
     * 查询个人动态
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public PageResult getOwnMovements(int page, int size, Long userId) {
        //查询分页数据
        PageResult pr = movementApi.getMovementsVo(userId,page,size);
        List<Movement> items = (List<Movement>) pr.getItems();
        if (items==null){
            return pr;
        }
        //查询用户信息
        UserInfo info = userInfoApi.findUserInfoById(userId);
        List<MovementsVo> list = new ArrayList<>();
        for (Movement item : items) {

            list.add(MovementsVo.init(info,item));
        }
        pr.setItems(list);
        return pr;
    }

    /**
     * 查询好友动态
     * 因为不需要计数，所以比较简单，直接查找好友的动态集合返回即可
     * @param page
     * @param size
     * @return
     */
    public PageResult getFriendsMovements(int page, int size) {
        //获得用户id
        Long userId = UserHolder.getUserId();
        //查询用户的好友动态集合
        List<Movement> friendsMovements=movementApi.getFriendsMovements(page,size,userId);

        List<MovementsVo>vo=friendsMovements.stream().map(item->{
            //查询用户信息
            UserInfo info = userInfoApi.findUserInfoById(item.getUserId());
            //构建返回对象
            return MovementsVo.init(info,item);

        }).collect(Collectors.toList());

        return new PageResult(page,size,0l,vo);
    }

    /**
     * 查询推荐动态
     * @param page
     * @param size
     * @return
     *
     *
     * 从redis获取当前用户的推荐PID列表
     * 如果不存在，调用API随机获取10条动态数据
     * 如果存在，调用API根据PID列表查询动态数据
     * 构造VO对象
     *
     * *
     */
    public PageResult getRecommendMovements(int page, int size) {
        //获取用户id以便从缓存中取出推荐的PId列表
        Long userId = UserHolder.getUserId();
        //取出推荐的Pid列表
        String str = redisTemplate.opsForValue().get(Constants.MOVEMENTS_RECOMMEND + userId);
        List<Movement>list =null;
        //判断split是否为空
        if (StringUtils.isEmpty(str)){
            //为空则生成随机十个推荐内容
            list= movementApi.getRandomMovements(size);

        }else {
            //用split方法以‘,’分割，获得数组方便进行分页查询
            String[] split = str.split(",");
            if ((page-1)*size>split.length){
                return new PageResult();
            }
            //不为空则按照分页方式取出pid去查询出对应的动态数据
            List<Long> PIds = Arrays.stream(split).skip((page - 1) * size).limit(size).map(item->{
                return Long.valueOf(item);
            }).collect(Collectors.toList());

            list=movementApi.getRecommendMovements(PIds);

        }

        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        Map<Long, UserInfo> info = userInfoApi.findUserInfoByIds(userIds, null);
        List<MovementsVo> vo =new ArrayList<>();
        for (Movement movement : list) {
            vo.add(MovementsVo.init(info.get(movement.getUserId()),movement));
        }

        return new PageResult(page,size,0l,vo);
    }

    /**
     * 通过动态id查询动态数据
     * @param id
     * @return
     */
    public MovementsVo getMovementByID(String id) {
        Movement movement=movementApi.getMovementByID(id);
        if (movement==null){
            throw new BusinessException(ErrorResult.contentError());
        }
        UserInfo info = userInfoApi.findUserInfoById(movement.getUserId());
        return MovementsVo.init(info,movement);
    }


    public Integer disLike(String id) {
        //判断是否已经存在点赞信息
        boolean flag =commentApi.hasComment(id,UserHolder.getUserId(),CommentType.LIKE);
        if (!flag){
            //如果不存在则抛出异常
            throw new BusinessException(ErrorResult.disLikeError());
        }
        Long userId = UserHolder.getUserId();
        Comment comment = new Comment();
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setUserId(userId);
        String key = Constants.MOVEMENTS_INTERACT_KEY+id;
        String hashKey=Constants.MOVEMENT_LIKE_HASHKEY+UserHolder.getUserId();
        redisTemplate.opsForHash().delete(key,hashKey);
        return commentApi.delete(comment,id);
    }

    public Integer like(String id) {
        //判断是否已经存在点赞信息
        boolean flag =commentApi.hasComment(id,UserHolder.getUserId(), CommentType.LIKE);
        if (!flag){
            //如果存在则抛出异常
            throw new BusinessException(ErrorResult.likeError());
        }
        Long userId = UserHolder.getUserId();
        Comment comment = new Comment();
        comment.setCommentType(CommentType.LIKE.getType());
        comment.setUserId(userId);
        String key = Constants.MOVEMENTS_INTERACT_KEY+id;
        String hashKey=Constants.MOVEMENT_LIKE_HASHKEY+UserHolder.getUserId();
        redisTemplate.opsForHash().put(key,hashKey,"1");
        return commentApi.save(comment,id);
    }

    public Integer unlove(String id) {
        //判断是否已经存在点赞信息
        boolean flag =commentApi.hasComment(id,UserHolder.getUserId(),CommentType.LOVE);
        if (!flag){
            //如果不存在则抛出异常
            throw new BusinessException(ErrorResult.disLikeError());
        }
        Long userId = UserHolder.getUserId();
        Comment comment = new Comment();
        comment.setCommentType(CommentType.LOVE.getType());
        comment.setUserId(userId);
        String key = Constants.MOVEMENTS_INTERACT_KEY+id;
        String hashKey=Constants.MOVEMENT_LOVE_HASHKEY+UserHolder.getUserId();
        redisTemplate.opsForHash().delete(key,hashKey);
        return commentApi.delete(comment,id);
    }

    public Integer love(String id) {
        //判断是否已经存在点赞信息
        boolean flag =commentApi.hasComment(id,UserHolder.getUserId(), CommentType.LOVE);
        if (!flag){
            //如果存在则抛出异常
            throw new BusinessException(ErrorResult.likeError());
        }
        Long userId = UserHolder.getUserId();
        Comment comment = new Comment();
        comment.setCommentType(CommentType.LOVE.getType());
        comment.setUserId(userId);
        String key = Constants.MOVEMENTS_INTERACT_KEY+id;
        String hashKey=Constants.MOVEMENT_LOVE_HASHKEY+UserHolder.getUserId();
        redisTemplate.opsForHash().put(key,hashKey,"1");
        return commentApi.save(comment,id);
    }
}